package com.sccl.autojob.skeleton.mq;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Description
 * @Auther Huang Yongxiang
 * @Date 2022/03/21 14:20
 */
public interface IConsumer<M> {
    /**
     * 阻塞的获取一条消息，可以决定是否将该消息取出，即移出队列
     *
     * @param topic     主题
     * @param isTakeout 是否移出队列，当为false时该方法将退化成非阻塞的
     * @return M
     * @author Huang Yongxiang
     * @date 2022/3/20 10:55
     */
    M takeMessageBlock(final String topic, final boolean isTakeout);

    M takeMessageNoBlock(final String topic, final boolean isTakeout);

    /**
     * 阻塞的获取指定数目的消息数，如果消息队列不存在指定数目的消息则阻塞，反之立即返回
     *
     * @param topic     主题名
     * @param count     要获取的数目
     * @param isTakeout 是否取出消息
     * @return java.util.List<M>
     * @author Huang Yongxiang
     * @date 2022/5/23 17:31
     */
    List<M> takeMessagesBlock(final String topic, final int count, final boolean isTakeout);

    List<M> takeMessagesBlock(final String topic, final int count, final boolean isTakeout, final long waitTime, TimeUnit unit);

    /**
     * 非阻塞的获取指定数目的消息数，不管消息队列是否存在指定数目的消息，都立即返回
     *
     * @param topic     主题名
     * @param count     要获取的数目
     * @param isTakeout 是否取出
     * @return java.util.List<M>
     * @author Huang Yongxiang
     * @date 2022/5/23 17:33
     */
    List<M> takeMessagesNoBlock(final String topic, final int count, final boolean isTakeout);

    List<M> takeMessageByRegexTopicBlock(final String regexTopic, final boolean isTakeout);

    List<M> takeMessageByRegexTopicNoBlock(final String regexTopic, final boolean isTakeout);


    MessageQueueContext.MessageQueue<MessageQueueContext.MessageEntry<M>> subscriptionMessage(String topic);

    /**
     * 阻塞的尝试订阅指定消息队列，如果存在则立即返回，否则将会等待指定时长，若期间创建则会立即返回，否则等
     * 到结束返回null
     *
     * @param topic 主题
     * @param wait  要阻塞获取的时长
     * @param unit  wait的时间单位
     * @return com.example.autojob.skeleton.mq.MessageQueueContext.MessageQueue<com.example.autojob.skeleton.mq.MessageQueueContext.MessageEntry < M>>
     * @author Huang Yongxiang
     * @date 2022/3/22 14:32
     */
    MessageQueueContext.MessageQueue<MessageQueueContext.MessageEntry<M>> subscriptionMessage(String topic, long wait, TimeUnit unit);

    void unsubscribe(String topic);

    /**
     * 取消订阅某个主题的消息队列，调用此方法可以激活组件的主题过期功能，即如果此时订阅数为0且消息堆积数为0，在wait时间后依然无生产者生产消息则会删除该主题
     *
     * @param topic 要取消订阅的主题名
     * @param wait  要等待的时间
     * @param unit  wait的单位
     * @return void
     * @author Huang Yongxiang
     * @date 2022/5/23 17:35
     */
    void unsubscribe(String topic, long wait, TimeUnit unit);
}
